本篇繼續介紹 Query DSL的 Full text queries
本篇介紹以下 full text queries
query_string query
query string 透過 "strict syntax(嚴格的語法)" 的parser來解析,
會先依據 operators 來 split(切分) query string, operators 像是 AND , OR , NOT
然後再一個一個 analyzes(分析) split text(切分的字串),之後才會去最匹配的動作
可以透過 query_string 來做到很複雜的搜尋,包含 使用wildcard 或 搜尋多個fields 等等,
但是 query是比較嚴格的,只要有無效的語法就會回傳錯誤,也因此官方也說明 query string 不建議拿來使用在 "search box(搜尋框)"
Example Request
GET /_search
{
"query": {
"query_string": {
"query": "(new york city) OR (big apple)", (1)
"default_field": "content" (2)
}
}
}
(1): 必填,欲用來搜尋的 query string
(2): 選填,如果 query string 沒有指定 field,就會使用此 default_field 的 field 來搜尋,如 default_field 也未提供,會使用index的設定 index.query.default_field ,而此設定預設是 * , * 指的是所有fields中可支援 term query 的fields
解析上述Request會如何parse
會把 query string 拆解成 new york city 和 big apple 兩部份,
而這兩部份一一被 content field 的 analyzer 轉成 tokens,然後才去做匹配的動作
[指定fields]
此外,可以直接在 query string 中指定 用某一字串搜尋特定fields,
例如: status:active 搜尋 status field 是否包含 activetitle:(quick OR brown) 搜尋 title field 是否包含 quick 或 brownauthor:"John Smith" 搜尋 author 要包含 phrase "John Smith"
[範圍(range)]
range 可用在 date, numeric, string等等,其中使用
中括號 [min TO max] 代表有包含邊界值,使用大括號 {min TO max} 則不包含邊界值
例如: date:[2012-01-01 TO 2012-12-31] 搜尋 date field 2012的每一天date:{* TO 2012-01-01} 搜尋 date field 2012以前的所有日期(不包括2012-01-01)
也可以並用中大括號, count:[1 TO 5} 搜尋 count field 數值1(包含) 至 5(不包含)
query_string query 功能很複雜很多樣,但也比較嚴格,如上述所說,只要語法是無效的就會報錯,
官方文件也提及此query適合給 "專業使用者"
simple_query_string query
query string 透過 "有限制可容錯" 的parser來解析,
根據 special operators 把 query string 切分成 terms,simple_query_string 不會因為無效的語法而報錯,他會忽略他
Example Request
GET /_search
{
"query": {
"simple_query_string" : {
"query": "\"fried eggs\" +(eggplant | potato) -frittata", (1)
"fields": ["title^5", "body"], (2)
"default_operator": "and" (3)
}
}
}
(1): 必填,即 query string
(2): 選填,欲搜尋的 fields (可多個), 其中 ^5,代表著 title 權重是 body 的5倍
(3): 選填,在 query string 中,如果沒有指定 operators ,則會使用此 default_operator 設定的operator, default_operator 可填的值有 OR 和 AND, default_operator 預設值為 OR
simple_query_string 支援的operators有:
+ 代表 AND 動作| 代表 OR 動作- 代表 NOT 否定" 包起來的字串代表要 phrase query* 放在term之後代表 prefix query( and ) 表示優先度較高~N 放在字詞之後代表 edit distance (fuzziness)~N 放在 phrase 之後 代表 slop amount不過上述的operators是可以透過參數 flags 來限制,預設此參數的值為 ALL,也就是這些 operators預設都支援
其實 default_operator 參數影響很大,舉個例子
GET /_search
{
"query": {
"simple_query_string": {
"fields": [ "content" ],
"query": "foo bar -baz"
}
}
}
原本的意圖是希望找出 content field 含有 foo 或 bar ,但是不含 baz ,
但因為 default_operator 是 OR,
所以實際上解析出來是,搜尋 content field 含有 foo 或 bar 或 任何不含baz,
也就是說 含有 baz 的documents也會被匹配得到,
那要怎麼達到原本意圖呢?
query string 改成 "foo bar +-baz" 即可,
代表著 欲搜尋 content field 含有 foo 或 bar "且" 不含baz,
官方文件有說明到,此 simple_query_string query 比 query_string 還要 "穩健(robust)",
適合直接拿來對外給使用者使用
intervals query
對於 matching terms 的組合,可以做到很細微的排序以及位置接近程度的控制
是由 matching rules 組成,最後組成的rules套用在指定的 field
支援的rules有:
以 match rule為例,提供了參數 max_gaps 控制匹配的terms之間可接受的最大的位置距離,
也提供了參數 ordered 設定匹配的terms的順序是否要和 query string中的位置順序一樣
intervals query 可以用到很精細微小,若有興趣深究可參考reference
common terms query
是個比較"專門"用來搜不常見的詞的query
不過因為在 es 7.3.0 被棄用了,且官方文件建議直接使用 match 所以在這就不多做介紹了
小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正
Full text queries
query string syntax
Intervals query